﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Common.Utility
{
    /// <summary>
    /// 简单反射处理类
    /// </summary>
    public class ReflectionHelper
    {
        /// <summary>
        /// 搜索指定接口所在程序集，并返回在程序集中定义并实现了此接口的类型
        /// </summary>
        /// <typeparam name="T">接口</typeparam>
        /// <returns></returns>
        public static Type[] GetTypes<T>()
        {
            return GetTypes(Assembly.GetAssembly(typeof(T)), typeof(T));
        }

        /// <summary>
        /// 在指定程序集中搜索指定接口返回在程序集中定义并实现了此接口的类型
        /// </summary>
        /// <param name="assembly">要搜索的程序集</param>
        /// <param name="iType">接口</param>
        /// <returns></returns>
        public static Type[] GetTypes(Assembly assembly, Type iType)
        {
            Type[] types = assembly.GetTypes().Where(t => t.IsInterface == false).ToArray();
            types = types.Where(t => t.GetInterface(iType.ToString()) != null).ToArray();
            return types;
        }

        /// <summary>
        /// 搜索指定接口所在程序集，并返回实现了指定接口和Attribute的类型
        /// </summary>
        /// <param name="iType">接口</param>
        /// <param name="attributeType">Attribute</param>
        /// <returns></returns>
        public static Type[] GetTypes(Type iType, Type attributeType)
        {
            Type[] types = GetTypes(Assembly.GetAssembly(iType), iType, attributeType);
            return types;
        }

        /// <summary>
        /// 搜索指定程序集中实现了指定接口和Attribute的类型
        /// </summary>
        /// <param name="assembly">程序集</param>
        /// <param name="iType">接口</param>
        /// <param name="attributeType">Attribute</param>
        /// <returns></returns>
        public static Type[] GetTypes(Assembly assembly, Type iType, Type attributeType)
        {
            Type[] types = GetTypes(assembly, iType);
            types = types.Where(t => t.IsDefined(attributeType, false)).ToArray();
            return types;
        }

        /// <summary>
        /// 搜索指定接口所在程序集，并返回所有实现了此接口的实例集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T[] GetInstance<T>()
        {
            Assembly assembly = Assembly.GetAssembly(typeof(T));
            return GetInstance<T>(assembly);
        }

        /// <summary>
        /// 搜索指定程序集，返回所有实现了指定接口的类型的实例集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="assembly"></param>
        /// <returns></returns>
        public static T[] GetInstance<T>(Assembly assembly)
        {
            Type[] types = GetTypes(assembly, typeof(T));
            List<T> list = new List<T>();
            foreach (Type type in types)
            {
                list.Add((T)assembly.CreateInstance(type.ToString()));
            }
            return list.ToArray();
        }
    }
}
